import { z } from "zod"; import { makeRoute } from "../lib"; import type { Env } from "./route"; import { AtUri } from "@atproto/syntax"; import { getFactsFromHomeLeaflets } from "./getFactsFromHomeLeaflets"; import { normalizeDocumentRecord } from "src/utils/normalizeRecords"; import { ids } from "lexicons/api/lexicons"; export type GetPublicationDataReturnType = Awaited< ReturnType<(typeof get_publication_data)["handler"]> >; export const get_publication_data = makeRoute({ route: "get_publication_data", input: z.object({ did: z.string(), publication_name: z.string(), }), handler: async ( { did, publication_name }, { supabase }: Pick, ) => { let pubLeafletUri; let siteStandardUri; if (/^(?!\.$|\.\.S)[A-Za-z0-9._:~-]{1,512}$/.test(publication_name)) { pubLeafletUri = AtUri.make( did, ids.PubLeafletPublication, publication_name, ).toString(); siteStandardUri = AtUri.make( did, ids.SiteStandardPublication, publication_name, ).toString(); } let { data: publication, error } = await supabase .from("publications") .select( `*, documents_in_publications(documents( *, comments_on_documents(count), document_mentions_in_bsky(count), recommends_on_documents(count) )), publication_subscriptions(*, identities(bsky_profiles(*))), publication_domains(*), leaflets_in_publications(*, documents(*), permission_tokens(*, permission_token_rights(*), custom_domain_routes!custom_domain_routes_edit_permission_token_fkey(*) ) )`, ) .or( `name.eq."${publication_name}", uri.eq."${pubLeafletUri}", uri.eq."${siteStandardUri}"`, ) .eq("identity_did", did) .order("uri", { ascending: false }) .limit(1) .single(); let leaflet_data = await getFactsFromHomeLeaflets.handler( { tokens: publication?.leaflets_in_publications.map( (l) => l.permission_tokens?.root_entity!, ) || [], }, { supabase }, ); // Pre-normalize documents from documents_in_publications const documents = (publication?.documents_in_publications || []) .map((dip) => { if (!dip.documents) return null; const normalized = normalizeDocumentRecord( dip.documents.data, dip.documents.uri, ); if (!normalized) return null; return { uri: dip.documents.uri, record: normalized, indexed_at: dip.documents.indexed_at, sort_date: dip.documents.sort_date, data: dip.documents.data, bsky_like_count: dip.documents.bsky_like_count, commentsCount: dip.documents.comments_on_documents[0]?.count || 0, mentionsCount: dip.documents.document_mentions_in_bsky[0]?.count || 0, recommendsCount: dip.documents.recommends_on_documents?.[0]?.count || 0, }; }) .filter((d): d is NonNullable => d !== null); // Pre-filter drafts (leaflets without published documents, not archived) const drafts = (publication?.leaflets_in_publications || []) .filter((l) => !l.documents) .filter((l) => !(l as { archived?: boolean }).archived) .map((l) => ({ leaflet: l.leaflet, title: l.title, permission_tokens: l.permission_tokens, // Keep the full leaflet data for LeafletList compatibility _raw: l, })); return { result: { publication, documents, drafts, leaflet_data: leaflet_data.result, }, }; }, });